iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0

摘要
Day 26 把 Day 25 的 request-scoped AuditEvent / Provenance resource preview 往 privacy boundary 補強:report 不只列出 retention policy 和 masked field categories,現在也會顯示 formal PHI masking policy evidence,並把 PHI masking status 寫入 request-scoped FHIR R4 AuditEventProvenance JSON preview。Day 26 讓 Quality Test Report 可以證明:即使輸入 Bundle 含 Patient direct identifiers,report 和 FHIR preview 仍只暴露 hash、policy evidence 和狀態。

這和「能不能交換」有什麼關係?

Day 25 可以回答:

Audit / Provenance readiness evidence 能不能形成實際 FHIR R4 AuditEvent / Provenance resource?

但正式交換前還有一個更具體的問題:

這些 report 和 FHIR preview 會不會把 PHI 帶出去?

如果一個 quality gate 可以產生 AuditEvent / Provenance preview,卻會在 report textarea、resource preview 或 evidence 欄位中 echo raw Bundle、Patient identifier、name、telecom、address 或 birthDate,那它仍然不能作為安全的 pre-exchange evidence。

Day 26 的目標不是變成 production PHI governance platform。
Day 26 的目標是:

request-scoped AuditEvent / Provenance preview -> formal PHI masking policy evidence

也就是說,今天新增的是「可檢查的 PHI masking policy evidence」:

  • 不是 persistent PHI repository。
  • 不是 database-backed retention workflow。
  • 不是正式 Consent / access control / operator identity audit。
  • 不是 SMART/OAuth privacy scope enforcement。
  • 不是把 masking result 寫到外部 FHIR server。
  • 而是先讓 report 能證明:direct Patient identifiers 和 raw Bundle JSON 不會出現在 Quality Test Report、AuditEvent preview 或 Provenance preview。

例如同一份 Bundle 進來時,Day 26 的判斷會是:

情境 結果
validation 尚未執行 PHI masking / privacy evidence NOT_EVALUATED
validation 已執行 PHI masking / privacy evidence PASSED,顯示 policy version 與 masked categories
input Bundle 含 Patient direct identifiers validation 可以執行,但 report 不 echo raw Bundle 或 direct identifier values
AuditEvent preview 產生 preview 只寫入 PHI masking policy version / status,不寫入 PHI 原文
Provenance preview 產生 preview 使用 urn:sha256:{inputHash} 指向 hashed Bundle source

這讓 report 可以明確說明:

PHI masking policy evidence 已能 request-scoped 產生。
但目前只展示 policy evidence,不持久化也不提交。

今天的實作範圍

Day 26 的 request / report flow 變成:

使用者上傳或貼上 Bundle
   │
   ├─ 執行原本 JSON / FHIR / TW Core / contract rules
   │
   ├─ terminology server evidence
   │     ├─ ValueSet/$expand
   │     └─ ValueSet/$validate-code
   │
   ├─ live FHIR metadata evidence
   │     └─ GET {FHIR_BASE_URL}/metadata
   │
   ├─ sandbox readiness evidence
   │     ├─ non-PHI preflight
   │     ├─ sandbox auth boundary
   │     └─ CapabilityStatement interaction declarations
   │
   ├─ PHI masking / privacy evidence
   │     ├─ masking policy version
   │     ├─ masked field categories
   │     ├─ masking check result
   │     ├─ raw Bundle policy
   │     └─ retention policy = request-scoped only / no persistent history
   │
   └─ AuditEvent / Provenance resource preview
         ├─ input SHA-256
         ├─ selected contract id/version
         ├─ gate outcome
         ├─ rule count
         ├─ terminology status
         ├─ metadata status
         ├─ sandbox status
         ├─ PHI masking status
         └─ generation policy = generated request-scoped only; not persisted; not submitted

最後 Quality Test Report 的 evidence layer 變成:

Quality Gate blocking result
   ├─ FHIR / TW Core / contract local rules
   ├─ Terminology server evidence
   ├─ Live FHIR metadata evidence
   ├─ Sandbox readiness evidence
   ├─ PHI masking / privacy evidence
   └─ AuditEvent / Provenance resource preview evidence
        ├─ AuditEvent JSON preview
        ├─ Provenance JSON preview
        └─ generation policy

PHI masking policy 做到哪裡?

Day 26 新增的是 formal policy evidence,不是 production PHI masking engine。

它會記錄:

  • masking policy version:phi-masking-policy#2026-08-27
  • masked field categories。
  • masking check result。
  • raw Bundle policy。
  • retention policy。
  • evidence statement。

目前禁止出現在 report / preview 的 direct PHI 類別是:

  • Patient.name
  • Patient.identifier.value
  • Patient.telecom
  • Patient.address
  • Patient.birthDate
  • raw Bundle JSON

這個 layer 的定位是:

report-visible PHI masking policy evidence
不是 production de-identification / pseudonymization engine

原因是 Day 26 還沒有 database-backed history、operator identity、access control、retention deletion workflow,也沒有正式的 masking rule registry 或外部 policy repository。

AuditEvent / Provenance preview 怎麼補強?

Day 26 沿用 Day 25 的 HAPI FHIR R4 model resource generation。

AuditEvent preview 現在除了 Day 25 的欄位,也會記錄:

  • phiMaskingPolicyVersion
  • phiMaskingStatus

Provenance preview 的 derivation display 也會加入:

phiMasking=PASSED

但 preview 仍然只用:

urn:sha256:{inputHash}

來指向輸入 Bundle 的 hash,不會把 raw Bundle 或 direct Patient identifier 寫入 FHIR resource preview。

Privacy / retention 邊界維持什麼?

Day 26 不把 raw Bundle echo 回 validation 後的頁面。

Bundle 仍然可以在 request scope 內被 parse / validate,但 validation 完成後,report 使用:

  • input SHA-256。
  • resource inventory。
  • rule evidence。
  • policy version。
  • masked field categories。
  • status evidence。

它不應輸出:

  • Patient.name 的實際值。
  • Patient.identifier.value 的實際值。
  • Patient.telecom 的實際值。
  • Patient.address 的實際值。
  • Patient.birthDate 的實際值。
  • raw Bundle JSON。

Retention policy 仍明確顯示:

request-scoped only; no persistent history

這表示目前版本仍然不會把 uploaded Bundle、terminology response、FHIR metadata response、sandbox response、AuditEventProvenance 或 PHI 寫進資料庫,也不會送到外部 FHIR server。

今天新增 / 調整的主要類別

  • PrivacyRetentionResult
  • PrivacyRetentionService

PrivacyRetentionResult 新增四個欄位:

  • maskingPolicyVersion
  • maskingCheckResult
  • rawBundlePolicy
  • maskedFieldCategories 新增 raw Bundle JSON

AuditProvenanceResourceService 也新增 PHI masking evidence:

  • phiMaskingPolicyVersion
  • phiMaskingStatus
  • phiMasking=PASSED

ParseController 調整 validation 後的頁面行為:

  • 不再把 raw input Bundle JSON echo 回 bundleJson textarea。

測試重點

今天新增 / 更新測試確認:

  • privacy / retention service 回傳 formal PHI masking policy evidence。
  • report UI 顯示 PHI masking / privacy evidence
  • report UI 顯示 phi-masking-policy#2026-08-27
  • report UI 顯示 raw Bundle JSON masking category。
  • validation 後頁面不 echo raw Bundle。
  • Bundle 含 Patient direct identifiers 時,report / preview 不顯示姓名、identifier value、telecom value、address line 或 birthDate value。
  • AuditEvent preview 包含 PHI masking policy version 與 status。
  • Provenance preview 使用 urn:sha256:{inputHash} 指向 hashed Bundle source。
  • Provenance preview 包含 phiMasking=PASSED

目前測試結果:

Tests run: 103, Failures: 0, Errors: 0, Skipped: 0

Day 26 完成後的邊界

完成後,專案的定位變成:

pre-exchange quality gate
   ├─ FHIR / TW Core validation
   ├─ partner contract rules
   ├─ contract lifecycle / compatibility
   ├─ unit normalization evidence
   ├─ terminology server evidence
   ├─ metadata preflight
   ├─ sandbox readiness evidence
   ├─ formal PHI masking / privacy evidence
   └─ request-scoped AuditEvent / Provenance preview

但它仍然不是:

  • production exchange platform。
  • full SMART/OAuth client。
  • live resource read/search executor。
  • Bundle submitter。
  • persistent audit log。
  • external FHIR AuditEvent / Provenance writer。
  • PHI repository。
  • production de-identification / pseudonymization engine。
  • retention deletion workflow。

下一步

之後預計從 Day 26 的 PHI masking evidence 往下做:

  • 真正的 SMART/OAuth sandbox token flow。
  • non-PHI test patient fixture / workflow。
  • allowlisted live Patient / Observation / DiagnosticReport read/search execution checks。
  • external FHIR AuditEvent / Provenance write policy。
  • database-backed persistent history。
  • retention deletion workflow。
  • deeper terminology governance,例如 inactive code policy、CodeSystem version、UCUM algebra。

Repository:twcore-data-quality-gate


上一篇
Day25 - Request-Scoped FHIR AuditEvent / Provenance Resource Preview
系列文
醫療資料通過標準驗證,就真的能交換嗎?——30 天打造 TW Core 資料品質閘門26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言